import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

import { useUserStore } from '@/store/user'
import { useRouterStore } from '@/store/router'
import { useAppStore } from '@/store/app'

import cache from '@/utils/cache'
import { Role } from '@/utils/enum'

NProgress.configure({ showSpinner: false })

const constantRoutes: RouteRecordRaw[] = [
  {
    path: '/redirect',
    children: [
      {
        path: '/redirect/:path(.*)?',
        component: () => import('@/layout/Router/Redirect.vue'),
      },
    ],
  },
  {
    path: '/404',
    component: () => import('../views/404.vue'),
  },
]

export const redirectRoutes: RouteRecordRaw[] = [
  {
    path: '/',
    redirect: '/home',
    name: 'UserRedirect',
    children: [],
    meta: { roles: [Role.USER] },
  },
  {
    path: '/',
    redirect: '/tag',
    name: 'AdminRedirect',
    children: [],
    meta: { roles: [Role.ADMIN] },
  },
]

const asyncRoutes: RouteRecordRaw[] = [
  {
    path: '/',
    component: () => import('@/layout/Theme/Vertical.vue'),
    children: [
      {
        path: 'profile',
        name: 'profile',
        component: () => import('@/views/profile/user/index.vue'),
        meta: {
          title: '个人中心',
          cache: true,
        },
        children: [
          {
            path: 'questionCollect',
            name: 'questionCollect',
            component: () => import('@/views/profile/user/components/QuestionCollect.vue'),
            meta: {
              title: '题目收藏',
              cache: true,
              roles: [Role.USER, Role.VIP],
            },
          },
          {
            path: 'answerCollect',
            name: 'answerCollect',
            component: () => import('@/views/profile/user/components/AnswerCollect.vue'),
            meta: {
              title: '回答收藏',
              cache: true,
              roles: [Role.USER, Role.VIP],
            },
          },
          {
            path: 'history',
            name: 'history',
            component: () => import('@/views/profile/user/components/History.vue'),
            meta: {
              title: '历史记录',
              cache: true,
              roles: [Role.USER, Role.VIP],
            },
          },
          {
            path: 'answer',
            name: 'answer',
            component: () => import('@/views/profile/user/components/Answer.vue'),
            meta: {
              title: '我的回答',
              cache: true,
              roles: [Role.USER, Role.VIP],
            },
          },
          {
            path: 'question',
            name: 'createQuestion',
            component: () => import('@/views/profile/user/components/Question.vue'),
            meta: {
              title: '创建问题',
              cache: true,
              roles: [Role.USER, Role.VIP],
            },
          },
        ],
      },
    ],
    meta: { roles: [Role.USER, Role.VIP] },
  },
  {
    path: '/',
    component: () => import('@/layout/Theme/Columns.vue'),
    children: [
      {
        path: '/profile',
        name: 'profile',
        component: () => import('@/views/profile/admin/index.vue'),
        meta: {
          title: '个人中心',
          cache: true,
        },
      },
    ],
    meta: { roles: [Role.ADMIN] },
  },
]

export const configRoutes: RouteRecordRaw[] = [
  {
    path: 'home',
    name: 'home',
    component: () => import('@/views/home/index.vue'),
    children: [],
    meta: { title: '主页', roles: [Role.USER, Role.VIP] },
  },
  {
    path: 'vip',
    name: 'vip',
    component: () => import('@/views/vip/index.vue'),
    children: [],
    meta: { title: '会员', hidden: true, roles: [Role.USER, Role.VIP] },
  },
  {
    path: 'bank/:bankId/question/:questionId',
    name: 'question',
    component: () => import('@/views/question/index.vue'),
    children: [],
    meta: { title: '题目详情', hidden: true, roles: [Role.USER, Role.VIP] },
  },
  {
    path: 'bank/:bankId',
    name: 'QuestionBank',
    component: () => import('@/views/question-bank/index.vue'),
    children: [],
    meta: { title: '题库详情', cache: true, hidden: true, roles: [Role.USER] },
  },
  {
    path: 'studyPath',
    name: 'studyPath',
    component: () => import('@/views/studyPath/index.vue'),
    children: [],
    meta: { title: '学习路线', roles: [Role.USER, Role.VIP] },
  },
  {
    path: 'tag',
    name: 'SysTagIndex',
    component: () => import('@/views/sys/tag/index.vue'),
    children: [],
    meta: { title: '标签管理', icon: 'icon-tag', cache: true, roles: [Role.ADMIN] },
  },
  {
    path: 'question',
    name: 'SysQuestionIndex',
    component: () => import('@/views/sys/question/index.vue'),
    children: [],
    meta: { title: '题目管理', icon: 'icon-book', cache: true, roles: [Role.ADMIN] },
  },
  {
    path: 'category',
    name: 'SysCategoryIndex',
    component: () => import('@/views/sys/category/index.vue'),
    children: [],
    meta: { title: '分类管理', icon: 'el-close', cache: true, roles: [Role.ADMIN] },
  },
  {
    path: 'user',
    name: 'SysUserIndex',
    component: () => import('@/views/sys/user/index.vue'),
    children: [],
    meta: { title: '用户管理', icon: 'icon-user', cache: true, roles: [Role.ADMIN] },
  },
  {
    path: 'dict',
    name: 'SysDictIndex',
    component: () => import('@/views/sys/dict/index.vue'),
    children: [],
    meta: { title: '字典管理', icon: 'icon-dict', cache: true, roles: [Role.ADMIN] },
  },
]

export const errorRoute: RouteRecordRaw = {
  path: '/:pathMatch(.*)',
  redirect: '/404',
}

export const router = createRouter({
  history: createWebHistory(import.meta.env.VITE_APP_BASE),
  routes: constantRoutes,
})

// 当前的角色
let currentRole = ''

// 路由跳转前
router.beforeEach(async (to, from, next) => {
  NProgress.start()
  const userStore = useUserStore()
  const routerStore = useRouterStore()
  const appStore = useAppStore()

  if (!appStore.dictList.length) await appStore.getDictListAction()

  // token存在的情况
  if (userStore.token && !userStore.user.id) {
    try {
      await userStore.getUserInfoAction()
    } catch (error) {
      // 请求异常，则跳转到登录页
      cache.removeToken()
      // next('/login')
      // return Promise.reject(error)
    }
  }

  if (currentRole === userStore.user.role) {
    next()
  } else {
    currentRole = userStore.user.role

    // resetRouter()
    // 重新挂载
    addRoutes()

    next({ ...to, replace: true })
  }
})

// 路由加载后
router.afterEach(() => {
  NProgress.done()
})

// 获取扁平化路由，将多级路由转换成一级路由
export const getKeepAliveRoutes = (rs: RouteRecordRaw[]): RouteRecordRaw[] => {
  const routerList: RouteRecordRaw[] = []

  rs.forEach((item) => {
    if (item.children && item.children.length > 0) {
      routerList.push(...getKeepAliveRoutes(item.children))
    } else {
      routerList.push(item)
    }
  })
  return routerList
}

// 动态生成路由数据
export const generateRoutes = (menuList: RouteRecordRaw[]): RouteRecordRaw[] => {
  const routerList: RouteRecordRaw[] = []
  menuList.forEach((menu) => {
    const userStore = useUserStore()
    if ((menu.meta?.roles! as Role[]).includes(userStore.user.role)) {
      const route: RouteRecordRaw = { ...menu, children: [] }

      // 有子菜单的情况
      if (menu.children && menu.children.length > 0) {
        route.children?.push(...generateRoutes(menu.children))
      }
      routerList.push(route)
    }
  })

  return routerList
}

export const resetRouter = () => {
  // 移除全部动态添加的路由
  const dynamicRoutes = router
    .getRoutes()
    .filter((route) => constantRoutes.some((constant) => constant.path === route.path))
  dynamicRoutes.forEach((route) => {
    router.removeRoute(route.name!)
  })

  addRoutes()
}

const addRoutes = async () => {
  const userStore = useUserStore()
  const routerStore = useRouterStore()

  // 重新挂载
  // 动态菜单+常量菜单
  const menuRoutes = await routerStore.getMenuRoutes()

  // 获取扁平化路由，将多级路由转换成一级路由
  const keepAliveRoutes = getKeepAliveRoutes(menuRoutes)

  const asyncRoute = asyncRoutes.find((route) => (route.meta!.roles as Role[]).includes(userStore.user.role))
  // 添加菜单路由
  asyncRoute!.children?.push(...keepAliveRoutes)
  router.addRoute(asyncRoute!)

  // 错误路由
  router.addRoute(errorRoute)
  // 保存路由数据
  routerStore.setRoutes(constantRoutes.concat(asyncRoutes))
}
